package com.campus.runrun.common.shiro;


import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

//标记当前类是一个Spring的配置类用于模拟Spring的配置文件
@Configuration
public class ShiroConfig {


    /**
     * 配置一个SecurityManager 安全管理器
     *
     */
    @Bean("securityManager")
    public SecurityManager securityManager(@Qualifier("myRealm") MyRealm myRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置realm.
        securityManager.setRealm(myRealm);
        return securityManager;
    }

    //配置一个自定义的Realm的bean，最终将使用这个bean返回的对象来完成我们的认证和授权
    @Bean(name = "myRealm")
    public MyRealm myRealm(){
        MyRealm myRealm=new MyRealm();
        return myRealm;
    }


    //配置一个Shiro的过滤器bean，这个bean将配置Shiro相关的一个规则的拦截
    //例如什么样的请求可以访问什么样的请求不可以访问等等
    @Bean
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager securityManager){
        //创建过滤器配置Bean
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        // 添加自己的过滤器并且取名为jwt
        Map<String, Filter> filterMap = new HashMap<>();
        shiroFilterFactoryBean.setFilters(filterMap);
        filterMap.put("jwt", new JWTFilter());
        Map<String,String> filterChainMap=new LinkedHashMap<>();
        filterChainMap.put("/login/wxMiniProGramLogin","anon");//配置登录请求不需要认证 anon表示某个请求不需要认证
        filterChainMap.put("/api/user/show","anon");//配置登录请求不需要认证 anon表示某个请求不需要认证
        // 放行服务须知获取方法
        // filterChainMap.put("/logout","logout");//配置登录的请求，登出后会请求当前用户的内存
        filterChainMap.put("/api/**","jwt");//配置登录的请求，登出后会请求当前用户的内存
        //filterChainMap.put("/**","anon");
        //设置权限拦截规则
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainMap);
        return shiroFilterFactoryBean;
    }

    /**
     * 开启Shiro注解支持（例如@RequiresRoles()和@RequiresPermissions()）
     * shiro的注解需要借助Spring的AOP来实现
     * @return
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }

    /**
     * 开启AOP的支持
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor=new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }



}
